<?php
/**
 * 用户基础模型
 */
namespace Common\Model;
use Think\Model;
class UserModel extends BaseModel{
	private static $instance=null;


	//用户头头像分组
	const USER_HEADPIC_DEVIDE  = 1000;

	//用户操作预置次数限定类型
	const LIMIT_TYPE_DAILY		= 1;
 	const LIMIT_TYPE_WEEKLY		= 2;
 	const LIMIT_TYPE_MONTHLY	= 3;
 	const LIMIT_TYPE_YEARLY		= 4;
 	const LIMIT_TYPE_FULLLIFE	= 5;//全生命周期


	//用户状态
	const USER_STATUS_All 		= 0;//
 	const USER_STATUS_NORMAL 	= 1;//正常用户
 	const USER_STATUS_SHUTUP 	= 2;//禁言用户
 	const USER_STATUS_DENYLOGIN= 3;//禁止登陆

	//性别
	const USER_SEX_ALL 			= 0;//全部
	const USER_SEX_MALE 		= 1;//男
	const USER_SEX_FEMALE 		= 2;//女
	const USER_SEX_OTHER 		= 3;//其他

	const FIELD_SEPARATOR   ="@@@";
	const LINE_SEPARATOR    ="###";

	public static function getUserStatus(){
		return array(
			self::USER_STATUS_All         =>'全部',
			self::USER_STATUS_NORMAL      =>'正常用户',
			self::USER_STATUS_SHUTUP      =>'禁言用户',
			self::USER_STATUS_DENYLOGIN   =>'禁止登陆'
		);
	}
	public static function getUserSex(){
		return array(
			self::USER_SEX_ALL            =>'全部',
			self::USER_SEX_MALE           =>'男',
			self::USER_SEX_FEMALE         =>'女',
			self::USER_SEX_OTHER          =>'保密'
		);
	}

	private function getInstance(){
		if(!self::$instance){
			self::$instance=M('u_user',null,DB_WEIXIN_CFG);
		}
		return self::$instance;
	}
	public function __construct(){
	}
	
	/* 获取微信平台请求的信息
	 * uid 用户ID
	 * self 0|1 0是自己 1是别人
	 * return  "data": {
        "sex": "4",
        "sexHtml": "",
        "userStatus": "2",
        "regTime": "1970-01-01  08:00:00",
        "lastLoginTime": "1970-01-01  08:00:00",
        "level": "2",
        "levelHtml": "老枪",
        "userTag": "1",
        "userTagHtml": "普通用户",
        "province": "820000",
        "city": "0",
        "EXP": "0",
        "bindPhone": "15657818590",
        "birthday": "0000-00-00",
        "consumeMoney": "0",
        "email": "",
        "lastLoginIP": "",
        "money": "0",
        "nickname": "Rick.Sun",
        "point": "100",
        "realName": "东野",
        "uid": "7",
        "userName": "Rick.Sun",
        "address": "澳门..."
    }
	*/
	public static function getUser($uid=0, $self=0){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		if(!$uid){
			return $dataFailure;
		}

		$userM=self::getInstance();
		$uinfo=$userM->where("uid={$uid}")->find();
		if(!$uinfo){
			$dataFailure['msg']='指定编号的用户不存在';
			return $dataFailure;
		}else{
			if(IS_BROADCAST){//外部系统，通过接口取对应属性值
				$userChangeful=UserModel::getUserChangeful_outer($uid);
				if(!is_null($userChangeful)){
					$uinfo['point'] 		= $userChangeful['point'];
					$uinfo['money'] 		= $userChangeful['money'];
					$uinfo['level'] 		= $userChangeful['level'];
					$uinfo['consumeMoney']  = $userChangeful['consumeMoney'];
					$uinfo['EXP']  			= $userChangeful['EXP'];
					$uinfo['vip']  			= $userChangeful['vip'];
				}
			}


			//获取用户微信账号信息
			$uinfoWeixin=M('u_user',null,DB_WEIXIN_CFG)->where("uid={$uid}")->find();
			$info = array();
			//卡券数量
			$cardNum = M('card_code',null,DB_WEIXIN_CFG)->where("uid={$uid} and status=1")->count();

			if($self == 0) {
				$info = UserModel::getUserNewMessageStatus($uid);
			}



			$userLevel 	= getLevelKv();
			$userTag 	= getUTagKv();
			$userVip    = getVipKv();

			$cfgSexArr=self::getUserSex();//C('USER_SEX');
			$cfgUserStatus=self::getUserStatus();

			$info['sex']		=$uinfo['sex'];
			$info['sexHtml']	=trim($cfgSexArr[$uinfo['sex']]);
			$info['userStatus']	=$cfgUserStatus[$uinfo['userStatus']];
			$info['regTime']	=date('Y-m-d  H:i:s',$uinfo['regTime']);
			$info['lastLoginTime']=date('Y-m-d  H:i:s',$uinfo['lastLoginTime']);
			$info['level'] 		= $uinfo['level'];
			$info['levelHtml']	= $userLevel[$uinfo['level']];
			
			$info['vip']		= $uinfo['vip'];
			$info['vipHtml']	= $userVip[$uinfo['vip']];
			
			$info['userTag'] 	= $uinfo['userTag'];
			$info['userTagHtml'] = $userTag[$uinfo['userTag']];
			$info['province'] 	= $uinfo['province'];
			$info['city'] 		= $uinfo['city'];
			$info['district'] 	= $uinfo['district'];
			$info['street']		= $uinfo['street'];
			$info['EXP']		= $uinfo['EXP'];
			$info['bindPhone'] 	= $uinfo['bindPhone'];
			$info['birthday'] 	= $uinfo['birthday'];
			$info['consumeMoney'] = $uinfo['consumeMoney'];
			$info['email'] 		= $uinfo['email'];
			$info['lastLoginIP'] = $uinfo['lastLoginIP'];
			$info['money'] 		= $uinfo['money'];
			$info['nickname'] 	= $uinfo['nickname'];
			$info['point'] 		= $uinfo['point'];
			$info['realName'] 	= $uinfo['realName'];
			$info['uid'] 		= $uinfo['uid'];
			$info['userName'] 	= $uinfo['userName'];
			$info['userStatus'] = $uinfo['userStatus'];
			$info['realName'] 	= $uinfo['realName'];
			$info['personal']	= $uinfo['personal'];
			$info['cardNum']	= $cardNum;
			$info['unionID'] 	= $uinfoWeixin['WX_unionID'];
			$info['openid']		= $uinfoWeixin['WX1_openID'];
			$info['subscribeOpenID']	= $uinfoWeixin['WX2_openID'];
			$info['app_openID']	= $uinfoWeixin['app_openID'];

			$regionKv = include_once(WEB_ROOT.'/data/area_info/'.$uinfo['province'].'.php');
			$info['address']=$regionKv[$uinfo['province']]['name']
				.'.'.$regionKv[$uinfo['city']]['name']
				.'.'.$regionKv[$uinfo['district']]['name']
				.'.'.$regionKv[$uinfo['street']]['name']
				.'.'.$uinfo['address'];

			$dataSuccess['data']=$info;
		}
		return $dataSuccess;
	}



	/**
	 * 用户签到
	 * Author: shijy
	 * @param $uid
	 * @return mixed
	 */
	public static	function userSign($uid){
		if(!USER_HOME_MYSIGN_ENABLE){
			return false;
		}
		$loginTime=time();

		$point = 0;

		$signM = M('u_sign',null,DB_WEIXIN_CFG);
		$where = "uid={$uid}";
		$data = $signM->where($where)->find();
		$lastLoginTime=$data['todaySignTime']+0;
		$lastTime = date('Ymd',$lastLoginTime);
		$nowTime = date('Ymd',$loginTime);

		if($nowTime == $lastTime){//同一天，退出
			return false;
		}
		$todayFirstTime =1;
		//签到奖励次数功能开关（月满签和特殊时间段）
		$signRewardSwitch = S("signRewardSwitch");
		if(!$signRewardSwitch){
			$signRewardSwitch = M("cfg_config",null,DB_MAIN_CFG)->where("cfgName = 'SIGN_REWARD_SWITCH'")->getField("cfgValue");
			S('signRewardSwitch',$signRewardSwitch);
		}
		$signRewardSwitch = explode(',',$signRewardSwitch);

		if($data){
			if(date('m',$loginTime) == date('m',$lastLoginTime)){		//是否为同一个月
				if($data['signDay']){
					$data['signDay'] .= ",".date('j',$loginTime);
				} else{
					$data['signDay'] = date('j', $loginTime);
				}
				$data['signMonthTimes'] += 1;
				$newData = array(
					"signDay"=>$data['signDay'],
					"signMonthTimes"=>$data['signMonthTimes'],
				);
			} else{
				$newData = array(
					"signMonthTimes"=>1,
					"signDay"=>date('j',$loginTime),
				);
			}

			$signAllTimes = $data['signAllTimes']+1;
			$newData['todaySignTime']= $loginTime;
			$newData['todaySignRank']= 0;
			$newData['signAllTimes']= $signAllTimes;

			$toastContent = "";
			//累计签到
			if(SIGN_REWARD_CUMULATIVE){
				$signLuckyTimes = 0;
				if(SIGN_REWARD_CUMULATIVE_DAY>0){
					$signLuckyTimes = floor($signAllTimes/SIGN_REWARD_CUMULATIVE_DAY) ;	//累计签到奖励抽奖次数
				}
				$newData['signLuckyTimes'] = $signLuckyTimes;
				if($signLuckyTimes > $data['signLuckyTimes']){
					$toastContent .= "<br/>".SIGN_REWARD_CUMULATIVE_DAY."日累计签到，抽奖次数+1";
				}
			}

			//月满签
			if($signRewardSwitch[0]==1 && $data['signMonthTimes'] == date('t',time())){
				$data['monFullSignTimes'] += 1;				//月满签奖励抽奖次数
				$newData['monFullSignTimes'] = $data['monFullSignTimes'];
				$toastContent .= "<br/>当月满签，抽奖次数+1";
			}

			//特殊时间段
			if($signRewardSwitch[1]==1){					//特殊时间期间奖励抽奖次数功能开关
				if($loginTime >= $signRewardSwitch[3] and $loginTime <= $signRewardSwitch[4]){
					$data['specialLuckyTimes'] += $signRewardSwitch[2];			//特殊时间期间，每天签到+抽奖机会
					$newData['specialLuckyTimes'] = $data['specialLuckyTimes'];
					$toastContent .= "<br/>每日签到活动，抽奖次数+".$signRewardSwitch[2];
				}
			}

			//连续登录+1,判断积分奖励情况
			$nextDayBeginTime = mktime(23,59,59,date('m',$lastLoginTime),date('d',$lastLoginTime),date('Y',$lastLoginTime));
			$nextDayEndTime = strtotime("+1 day",$nextDayBeginTime);
			if($loginTime > $nextDayBeginTime && $loginTime <= $nextDayEndTime){
				$continueDay = $data['continueDay']+1;
			} else {
				$continueDay = 1;
			}
			$newData['continueDay'] = $continueDay;
			$signM->where($where)->setField($newData);
			session("signToast",$toastContent);
		}else{
			$signAllTimes = 1;
			$newData = array(
				'uid'				=> $uid,
				'signAllTimes'		=> $signAllTimes,
				'signMonthTimes'	=> 1,
				'signDay'			=> date('j',$loginTime),
				'todaySignRank' 	=> 0,
				'todaySignTime' 	=> $loginTime,
				'signLuckyTimes'	=> 0,
				'monFullSignTimes'	=> 0,
				'specialLuckyTimes'	=> 0,
				'continueDay'		=> 1,
			);
			//特殊时间段
			if($signRewardSwitch[1]==1){					//特殊时间期间奖励抽奖次数功能开关
				if($loginTime >= $signRewardSwitch[3] and $loginTime <= $signRewardSwitch[4]){
					$newData['specialLuckyTimes'] = $signRewardSwitch[2];	//特殊时间期间，每天签到+抽奖机会
					$toastContent = "<br/>每日签到活动，抽奖次数+".$signRewardSwitch[2];
					session("signToast",$toastContent);
				}
			}
			$continueDay = 1;
			$signM->add($newData);
		}

		$extra = M('lucky_prize',null,DB_MAIN_CFG)->where("type=".SignLuckyModel::PRIZE_TYPE_SIGN_CONTINUE." and prizeType=".ELEMENT_TYPE_POINT)->order('prizeRank DESC')->field("prizeRank,extra")->select();
		foreach($extra as $val){
			if($continueDay >= $val['prizeRank']){
				$point = $val['extra'];
				break;
			}
		}
		$info['todayFirstTime'] = $todayFirstTime;
		$info['point'] = $point;

		if($info['todayFirstTime']==1){
			//签到日志
			self::addSignLog($uid,$info['point'],$signAllTimes);
			//签到奖励积分
			if($info['point'] > 0){
				self::plusPoint($uid,-1,$info['point'],OPT_LOGIN);
			}
			//日签到排行
			self::todaySignRank($uid);
			//登录 变动签到排名
			self::signRanking();
		}

		return $info;
	}

	/**
	 * 获取用户签到次数和奖励积分, 并计算抽奖次数
	 * Author:wwl
	 * return
	 */
	public static function getSignTimes($uid){
		$signM = M('u_sign',null,DB_MAIN_CFG);
		$data = $signM->where("uid={$uid}")->field('signAllTimes,signMonthTimes,signDay,usedTimes,todaySignRank,monFullSignTimes,signLuckyTimes,specialLuckyTimes')->find();
		$time = time();
		$luckyTimes = $data['signLuckyTimes'] + $data['monFullSignTimes'] + $data['specialLuckyTimes'];	//总抽奖次数
		if($luckyTimes <= $data['usedTimes']){
			$data['luckyTimes'] = 0;
		}else $data['luckyTimes'] = $luckyTimes-$data['usedTimes'];

		$start = mktime(0,0,0,date("m",$time),date("d",$time),date("Y",$time));
		$end = mktime(23,59,59,date("m",$time),date("d",$time),date("Y",$time));
		$data['point'] = M('u_sign_log',null,DB_MAIN_CFG)->where("uid={$uid} and addTime between {$start} and {$end}")->getField("addPoint");
		return $data;
	}


	/**
	 * 排名统计
	 * author: wwl <wuwl@soe-soe.com>
	 * Address: 浙江宣逸网络科技有限公司
	 */
	public static function signRanking(){
		$begin = microtime(true);
		$lastRankTime = S("signRankTime")+0;
		$spacingTime = $begin-$lastRankTime;	//实际间隔时间
		$spacingMaxTime = 300;			//最大间隔时间
		if($spacingTime > $spacingMaxTime){
			S("signRankTime", microtime(true));
			$signM = M('u_sign',null,DB_MAIN_CFG);
//			$dataOuterFile="/home/www/star/server/data/userSign_".$uid;
			$dataOuterFile=C('LOAD_DATA_DIR')."userSign";
			unlink($dataOuterFile);

			$count = $signM->count();
			$items = 10000;
			$parts = ceil($count/$items);
			for ($i=0;$i<$parts;$i++){
				$startItem = $i*$items;
				$sql = $signM->order('signAllTimes DESC,uid ASC')->field('uid,signAllTimes')->limit($startItem,$items)->select();
				foreach($sql as $key => $val){
					$sql[$key]['rank'] = $key+1;
					$str = $val['uid'].self::FIELD_SEPARATOR.$val['signAllTimes'].self::FIELD_SEPARATOR.$sql[$key]['rank'].self::LINE_SEPARATOR;
					file_put_contents($dataOuterFile,$str,FILE_APPEND);
				}
				unset($sql);
			}

			$sql = <<<SQL
LOAD DATA LOCAL INFILE '%s' REPLACE INTO table `%s`.u_sign_rank FIELDS TERMINATED BY '%s' LINES TERMINATED BY '%s' (uid,signAllTimes,rank);
SQL;
			$sql = sprintf($sql,$dataOuterFile,C('DB_NAME'),self::FIELD_SEPARATOR,self::LINE_SEPARATOR);
			$signM->execute($sql);

		}
		return;
	}

	/**
	 * 读取排名
	 * author:wwl
	 */
	public static function getSignRank($uid){
		$rank = M('u_sign_rank',null,DB_MAIN_CFG)->where("uid={$uid}")->getField("rank");
		return $rank;
	}

	/**
	 * 读取签到相关所有数据信息
	 * author: wwl <wuwl@soe-soe.com>
	 * Return: array
	 * Address: 浙江宣逸网络科技有限公司
	 */
	public static function sign($uid,$from=CLIENT_FROM_PC){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		if(!$uid){
			return $dataFailure;
		}
		$signInfo = self::getSignTimes($uid);				  //取签到日子、总签到次数、月签到次数、日签到排名、奖励积分(u_sign)
		$signDay = explode(',',$signInfo['signDay']);
		$weekAndDay = UtilsModel::getWeekAndDay(time());      //本月第一天星期几及本月天数,本次登录日期
		$rank = self::getSignRank($uid);					  //取总排名(u_sign_rank)

		$data['signInfo'] = $signInfo;
		$data['signDay'] = $signDay;
		$data['weekAndDay'] = $weekAndDay;
		$data['rank'] = $rank;

		if($from == CLIENT_FROM_PC){
			$basePic = SignLuckyModel::getBasePicAndRegulations();//取底图(lucky_Prize)
			$set = SignLuckyModel::getLuckyPrizeNote();           //奖品说明(lucky_prize)
			$myPrize = UserModel::getLuckyPrizeLog($uid,SignLuckyModel::PRIZE_TYPE_SIGN_LUCKY,1,8,CLIENT_FROM_PC);//我的奖品(u_lucky_log)
			$data['basePic'] = $basePic;
			$data['set'] = $set;
			$data['myPrize'] = $myPrize;
		}
		$dataSuccess['data'] = $data;
		return $dataSuccess;
	}

	
	/**
	 * 微信登陆
	 * @param $open_id
	 * @param $nickname
	 * @param $pic
	 * @param int $sex
	 * @param int $appid
	 * @return array
	 */
	public static function wechatLogin($open_id,$nickname,$pic,$sex=3,$appid=0){
		$now        = time();
		$sex 		= intval($sex) ? $sex : 3;
		$nickname 	= addslashes($nickname);

		$u_user_baseM 	= M('u_user', null, DB_WEIXIN_CFG);
		$userinfo = $u_user_baseM->where(" openid='{$open_id}' ")->find();

		if(!$userinfo){
			$userinfo=array('openid'=>$open_id,'nickname'=>$nickname,'wcapp'=>$appid);
			$uid=$u_user_baseM->add($userinfo);
		}else{
			$uid=$userinfo['uid'];
		}
		UtilsModel::saveUserHeadPic(file_get_contents($pic), $uid);//更新头像
		return array('uid'=>$uid);

	}

	/**
	 * 添加登陆日志
	 * Author: shijy
	 * @param $uid
	 * @param $clientFrom
	 * @return bool
	 */
	private static function addLoginLog($uid,$clientFrom){
		if(!$uid){
			return false;
		}
		$loginIP=get_client_ip();
		$now=time();
		$loginData=array(
			'uid'=>$uid,
			'addTime'=>$now,
			'clientFrom'=>$clientFrom,
			'loginIP'=>$loginIP
		);
		M('u_login_log',null,DB_MAIN_CFG)->add($loginData);

		$data=array(
			'lastLoginTime'=>$now,
			'lastLoginIP'=>$loginIP
		);
		self::getInstance()->where("uid={$uid}")->save($data);
		return true;
	}



	/**
	 *
	 * 添加签到日志
	 * Author: wwl
	 * @param $uid
	 * @param $point 签到奖励积分
	 * @param $signAllTimes 总签到次数
	 * @return bool
	 */
	private static function addSignLog($uid,$point,$signAllTimes){
		if(!$uid){
			return false;
		}
		$now = time();
		$data = array(
			'uid' 		=> $uid,
			'addTime'	=> $now,
			'addPoint'	=> $point,
			'signAllTimes'	=> $signAllTimes,
		);
		M('u_sign_log',null,DB_MAIN_CFG)->add($data);
		return true;
	}





	/**
	 * 根据用户编号获取头像路径
	 * Author: shijy
	 * @param $uid
	 * @return string
	 */
	public static function getHeadPicPath($uid){
		$name 	= $uid;
		$subDir = $uid % self::USER_HEADPIC_DEVIDE;
		return "headpic/{$subDir}/{$name}.jpg";
	}

	/**
	 * 获取完整头像显示路径
	 * Author: shijy
	 * @param $uid
	 * @return string
	 */
	public static function getHeadPicFullPath($uid){
		return USER_HEADPIC_SHOW_PATH.self::getHeadPicPath($uid);
	}

	/**
	 * 根据用户编号获取用户大转盘中奖记录
	 * author: wwl <wuwl@soe-soe.com>
	 * Return: array
	 * Address: 浙江宣逸网络科技有限公司
	 */
	public static function getLuckyPrizeLog($uid,$type=SignLuckyModel::PRIZE_TYPE_SIGN_LUCKY,$page,$pageSize=12,$from=0){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		if(!$uid){
			return $dataFailure;
		}
		$luckyM = M('u_lucky_log',null,DB_MAIN_CFG);
		$where = "uid={$uid} and type={$type} and prizeRank>0";
		$dataSuccess['total'] = $luckyM->where($where)->count();//获取数据总条数
		$dataSuccess['page'] = max($page , 1);//返回当前页
		$dataSuccess['totalPage'] = ceil($dataSuccess['total']/$pageSize);//总共页数
		$dataSuccess['nextPage'] = $dataSuccess['page'] >= $dataSuccess['totalPage'] ? 0 : 1;//是有有下一页
		$offset=($dataSuccess['page']-1) * $pageSize;

		$data = $luckyM->where($where)->limit($offset,$pageSize)->order("addTime DESC")->select();

		if($data){
			foreach($data as $key => $val){
				switch($val['prizeRank']){
					case SignLuckyModel::LUCKY_PRIZE_NULL:
						$data[$key]['prizeRank'] = "未中奖";
						break;
					case SignLuckyModel::LUCKY_PRIZE_FIRST:
						$data[$key]['prizeRank'] = "一等奖";
						break;
					case SignLuckyModel::LUCKY_PRIZE_SECOND:
						$data[$key]['prizeRank'] = "二等奖";
						break;
					case SignLuckyModel::LUCKY_PRIZE_THIRD:
						$data[$key]['prizeRank'] = "三等奖";
						break;
					case SignLuckyModel::LUCKY_PRIZE_FORTH:
						$data[$key]['prizeRank'] = "四等奖";
						break;
					case SignLuckyModel::LUCKY_PRIZE_FIFTH:
						$data[$key]['prizeRank'] = "五等奖";
						break;
				}
				if($from == CLIENT_FROM_PC){
					$data[$key]['prizeNote'] = str_replace("<br/>",",",$val['prizeNote']);
				}

			}
		}
		$dataSuccess['data'] = $data;
		return $dataSuccess;
	}
 



	/**
	 * 添加OPT操作日志
	 *Author:wwl
	 */
	public static function operationLog($uid,$operation,$remark){
		$dataSuccess = array('status'=>self::SUCCESS,'msg'=>'成功');
		$dataFailure = array('status'=>self::FAILURE,'msg'=>'无效参数');
		if(!$uid || !$operation){
			return $dataFailure;
		}
		$data = array(
			'uid'		=> $uid,
			'operation'	=> $operation,
			'addTime'	=> time(),
			'remark'	=> $remark,
		);
		$id = M('u_operation_log',null,DB_MAIN_CFG)->add($data);
		if($id){
			return $dataSuccess;
		} else {
			return $dataFailure;
		}
	}


}